package com.iwechat;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Properties 工厂<br>
 */
public class PropertyUtils {
    private static final Logger            logger     = LoggerFactory.getLogger(PropertyUtils.class);
    private static final PropertyUtils     instance   = new PropertyUtils();
    private static final String            STORE_PATH = "properties";
    private static final String            ENV        = "env";
    private static Map<String, Properties> propMap;

    /**
     * 获取实例
     * 
     * @return
     */
    public static PropertyUtils getInstance() {
        return instance;
    }

    private PropertyUtils() {
        init();
    }

    /**
     * 初始化properties文件<br>
     * 作为public方法可以供外部调用重新加载配置文件
     */
    public static void init() {
        String propPath = getConfigPath(STORE_PATH);
        logger.info("init properties from :" + propPath);
        Map<String, Properties> propMap = new HashMap<String, Properties>();
        InputStreamReader isr = null;
        FileInputStream fis = null;
        try {
            File dir = new File(propPath);
            if (dir.exists()) {
                if (dir.isDirectory()) {
                    File[] propArr = dir.listFiles();
                    for (File file : propArr) {
                        String key = file.getName();
                        // 只加载.properties文件
                        if (key.endsWith(".properties")) {
                            fis = new FileInputStream(file);
                            isr = new InputStreamReader(fis);
                            Properties p = new Properties();
                            p.load(isr);
                            key = key.substring(0, key.lastIndexOf('.'));
                            propMap.put(key, p);
                        }
                        if (fis != null) {
                            try {
                                fis.close();
                            } catch (Exception e) {
                            }
                        }
                        if (isr != null) {
                            try {
                                isr.close();
                            } catch (Exception e) {
                            }
                        }
                    }
                } else {
                    logger.error(propPath + "\t不是一个文件目录!!!");
                }
            } else {
                logger.error(propPath + "\t文件目录不存在,请核实!!!");
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (Exception e) {
                }
            }
            if (isr != null) {
                try {
                    isr.close();
                } catch (Exception e) {
                }
            }
        }
        if (PropertyUtils.propMap != null) {
            PropertyUtils.propMap.clear();
        }
        PropertyUtils.propMap = propMap;
    }

    /**
     * 从指定配置文件中获取指定key的Boolean型值
     *
     * @param propFileName
     *            配置文件名
     * @param key
     *            key
     * @return Boolean value
     */
    public boolean getBooleanValue(String propFileName, String key) {
        String sValue = this.getValue(propFileName, key);
        if (sValue == null || "".equals(sValue)) {
            sValue = "false";
        }
        try {
            return Boolean.parseBoolean(sValue);
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 从指定配置文件中获取指定key的Double型值
     *
     * @param propFileName
     *            配置文件名
     * @param key
     *            key
     * @return Double value
     */
    public double getDoubleValue(String propFileName, String key) {
        String sValue = this.getValue(propFileName, key);
        if (sValue == null || "".equals(sValue)) {
            sValue = "0.0";
        }
        try {
            return Double.parseDouble(sValue);
        } catch (NumberFormatException e) {
            return 0.0;
        }
    }

    /**
     * 从指定配置文件中获取指定key的Float型值
     *
     * @param propFileName
     *            配置文件名
     * @param key
     *            key
     * @return Float value
     */
    public float getFloatValue(String propFileName, String key) {
        String sValue = this.getValue(propFileName, key);
        if (sValue == null || "".equals(sValue)) {
            sValue = "0.0";
        }
        try {
            return Float.parseFloat(sValue);
        } catch (NumberFormatException e) {
            return 0.0f;
        }
    }

    /**
     * 从指定配置文件中获取指定key的整数值
     *
     * @param propFileName
     *            配置文件名称
     * @param key
     *            key
     * @return int value
     */
    public int getIntValue(String propFileName, String key) {
        String sValue = this.getValue(propFileName, key);
        if (sValue == null || "".equals(sValue)) {
            sValue = "0";
        }
        try {
            return Integer.parseInt(sValue);
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    /**
     * 从指定配置文件中获取指定key的Long型值
     *
     * @param propFileName
     *            配置文件名
     * @param key
     *            key
     * @return Long value
     */
    public Long getLongValue(String propFileName, String key) {
        String sValue = this.getValue(propFileName, key);
        if (sValue == null || "".equals(sValue)) {
            sValue = "0";
        }
        try {
            return Long.parseLong(sValue);
        } catch (NumberFormatException e) {
            return 0L;
        }
    }

    /**
     * 从指定配置文件中获取指定key的String型值
     *
     * @param propFileName
     *            配置文件名
     * @param key
     *            key
     * @return String value
     */
    public String getStringValue(String propFileName, String key) {
        return this.getValue(propFileName, key);
    }

    /**
     * 获取配置项的值
     * 
     * @param propFileName
     *            不带properties后缀的文件名
     * @param key
     *            properties文件中key
     * @return
     */
    private String getValue(String propFileName, String key) {
        Properties env = propMap.get(ENV);
        if (env != null) {
            String envPrefix = env.getProperty(ENV, "");
            if (StringUtils.isNotEmpty(envPrefix)) {
                propFileName = envPrefix + "_" + propFileName;
            }
        }
        String retVal = "";
        Properties p = propMap.get(propFileName);
        if (p != null) {
            retVal = p.getProperty(key, "");
        }
        return retVal;
    }

    /**
     * 获取指定文件的url path<br>
     *
     * @param fileName
     * @return
     */
    public static String getConfigPath(String fileName) {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        URL url = cl.getResource(fileName);
        String path;
        if (url != null) {
            path = url.toString();
        } else {
            path = "/";
        }
        // 去掉 file:\ 或 file:/
        if (path.startsWith("file:")) {
            path = path.substring(6);
            // 若不是"F:/..."这种格式，则在开头加上"/",格式为"/home/..."
            if (path.charAt(1) != ':') {
                path = File.separator + path;
            }
        }
        return path;
    }
}
